/**
 * TodoList的Model
 */

import { default as xs, Stream } from 'xstream';
import { TodoState, TodoListAction, TodoListReducer, TodoListState } from '../../types';

/**
 * 根据路由返回过滤的方法
 * @param route 
 */
function getFilterFn(route : string) : (item : TodoState) => boolean {
  switch (route) {
    case '/active': return ((item : TodoState) => item.completed === false);
    case '/completed': return ((item : TodoState) => item.completed === true);
    default: return () => true; // allow anything
  }
}

/**
 * 获取当前系统时间
 */
let uuid = Date.now();

export default function model(actions : TodoListAction) : Stream<TodoListReducer | {}>{
    // 初始化状态
    const initialReducer$ = xs.of<TodoListReducer>((prevState : TodoListState) => {
        if (prevState && prevState.list) {
            return prevState;
        } else {
            return {
                inputValue: '',
                list: [],
                filter: '',
                filterFn: () => true, // allow anything
            };
        }
    });
    // 路由改变的监听
    const changeRouteReducer$ = actions.changeRoute$
        .startWith('/')
        .map<TodoListReducer>(path => {
            // 过滤方法
            const filterFn = getFilterFn(path);
            // 改变监听字符串和监听方法
            return function changeRouteReducer(prevState : TodoListState) {
                return {
                    ...prevState,
                    filter: path.replace('/', '').trim(),
                    filterFn: filterFn,
                }
            };
        });
    // 输入框值改变的监听
    const updateInputValueReducer$ = actions.updateInputValue$
        .map<TodoListReducer>(inputValue => function updateInputValue(prevState : TodoListState) {
            // 改变输入值
            return {...prevState, inputValue: inputValue};
        });
    // 清空输入值的监听
    // 同时判断取消输入和插入TODO
    const clearInputReducer$ = xs.merge(actions.cancelInput$, actions.insertTodo$)
        .mapTo<TodoListReducer>(function clearInputReducer(prevState : TodoListState) {
            // 清空输入值
            return {...prevState, inputValue: ''};
        });
    // 插入Todo的监听
    const insertTodoReducer$ = actions.insertTodo$
        .map<TodoListReducer>(content => function insertTodoReducer(prevState : TodoListState) {
            const newTodo = {
                key: uuid++,
                title: content,
                completed: false,
                editing: false,
            };
            return {
                ...prevState,
                list: prevState.list.concat(newTodo),
            }
        });
    // 切换所有的监听
    const toggleAllReducer$ = actions.toggleAll$
        .map<TodoListReducer>(isToggled => function toggleAllReducer(prevState : TodoListState) {
            return {
                ...prevState,
                list: prevState.list.map(item =>
                    ({...item, completed: isToggled})
                ),
            }
        });
    // 删除完成的监听
    const deleteCompletedReducer$ = actions.deleteCompleted$
        .mapTo<TodoListReducer>(function deleteCompletedsReducer(prevState : TodoListState) {
            return {
                ...prevState,
                list: prevState.list.filter(task => task.completed === false),
            };
        });
    // 合并
    return xs.merge(
        initialReducer$,
        updateInputValueReducer$,
        changeRouteReducer$,
        clearInputReducer$,
        insertTodoReducer$,
        toggleAllReducer$,
        deleteCompletedReducer$
    );
}


